package com.wymobilearchitecture.study.thread;

import com.example.w_library.log.WLog;

public class ThreadStateTest {

    public ThreadStateTest(){

        waitAndNotify();

        join();

        sleep();

    }


    /**
     * wait-notify
     * 适用于多线程同步,一个线程需要等待另一个线程的执行结果,或者部分结果
     */
    private void waitAndNotify(){
        Thread thread1 = new Thread(new Runnable1());
        thread1.start();
        Thread thread2 = new Thread(new Runnable2());
        thread2.start();
    }

    private final Object object = new Object();
    //防止出现先执行 object.notify(); 情况导致线程假死
    private volatile boolean hasNotify = false;

    class Runnable1 implements Runnable{
        @Override
        public void run() {
            WLog.e("waitAndNotify: thread1 start");
            //把 object 对象作为资源对象
            synchronized (object){
                try {
                    if (!hasNotify){
                        object.wait();
                    }
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
            WLog.e("waitAndNotify: thread1 end");
        }
    }

    class Runnable2 implements Runnable{
        @Override
        public void run() {
            WLog.e("waitAndNotify: thread2 start");
            synchronized (object){
                object.notify();
                hasNotify = true;
            }
            WLog.e("waitAndNotify thread2 end");
        }
    }


    /**
     * join
     * 一个线程需要等待另一个线程执行完才能继续的场景,join 相当于向当前线程插入一条任务,
     * 只有任务执行完成之后,当前线程才会继续执行
     */
    private void join(){

        Thread threadJoin = new Thread(new Runnable() {
            @Override
            public void run() {
                WLog.e("join1: " + System.currentTimeMillis());
                try {
                    Thread.sleep(1000);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                WLog.e("join2: " + System.currentTimeMillis());
            }
        });
        threadJoin.start();
        try {
            threadJoin.join();
        } catch (InterruptedException e) {
            e.printStackTrace();
        }

        WLog.e("join3: " + System.currentTimeMillis());

    }


    /**
     * sleep
     * 使调用线程进入休眠状态,一般情况下会释放资源锁对象,
     * 但在一个 synchronized 块中执行 sleep,线程虽然会休眠,但不会释放子资源对象锁
     * 当线程3先运行的情况下,线程4需要等待线程3睡眠完成释放object资源之后才能执行
     */
    private void sleep() {
        new Thread(new Runnable3()).start();
        new Thread(new Runnable4()).start();
    }

    class Runnable3 implements Runnable{
        @Override
        public void run() {
            WLog.e("sleep: thread3 start");
            synchronized (object){
                try {
                    Thread.sleep(1000);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                WLog.e("sleep: thread3 end");
            }
        }
    }

    class Runnable4 implements  Runnable{
        @Override
        public void run() {
            synchronized (object){
                WLog.e("sleep: thread3 start");
                WLog.e("sleep: thread3 end");
            }
        }
    }
}
